package com.example.demo.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.demo.entity.UserExcel;
import com.example.demo.utils.ValidationUtils;
import com.example.demo.vo.UserExcelVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Excel 数据导入，如何更优雅的进行数据校验？
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class UserExcelController {

    @PostMapping("/v1/importExcel")
    public UserExcelVO importExcel(@RequestParam("file") MultipartFile file) {
        List<UserExcel> list = null;
        List<UserExcel> fail = new ArrayList<>();
        UserExcelVO userExcelVO = new UserExcelVO();
        String mobieReg = "^[1][3,4,5,7,8][0-9]{9}$";
        try {
            list = EasyExcel.read(file.getInputStream(), UserExcel.class, new ModelExcelListener()).sheet().doReadSync();
            list.forEach(data -> {
                //处理姓名的校验
                if (StringUtils.isEmpty(data.getName()) || data.getName().length() > 4) {
                    fail.add(data);
                    return;
                }
                //处理手机号的校验
                if (StringUtils.isEmpty(data.getMobile()) || !data.getMobile().matches(mobieReg)) {
                    fail.add(data);
                    return;
                }
                //以下根据字段多少可能有n个if

            });
            userExcelVO.setFail(fail);
            list.removeAll(fail);
            userExcelVO.setSuccess(list);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return userExcelVO;
    }


    @PostMapping("/v2/importExcel")
    public UserExcelVO importExcelV2(@RequestParam("file") MultipartFile file) {
        List<UserExcel> list = null;
        List<UserExcel> fail = new ArrayList<>();
        UserExcelVO userExcelVO = new UserExcelVO();
        try {
            list = EasyExcel.read(file.getInputStream(), UserExcel.class, new ModelExcelListener()).sheet().doReadSync();
            list.forEach(data -> {
                Set<ConstraintViolation<UserExcel>> violations = ValidationUtils.getValidator().validate(data);
                if (violations.size() > 0) {
                    fail.add(data);
                }
            });
            userExcelVO.setFail(fail);
            list.removeAll(fail);
            userExcelVO.setSuccess(list);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return userExcelVO;
    }


    public static class ModelExcelListener extends AnalysisEventListener<UserExcel> {
        private List<UserExcel> datas = new ArrayList<>();

        /**
         * 通过 AnalysisContext 对象还可以获取当前 sheet，当前行等数据
         */
        @Override
        public void invoke(UserExcel data, AnalysisContext context) {
            //数据存储到list，供批量处理，或后续自己业务逻辑处理。
            log.info("读取到数据{}", data);
            datas.add(data);
            //根据业务自行处理，可以写入数据库等等


        }

        //所有的数据解析完了调用
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            log.info("所有数据解析完成");
        }
    }
}

